package com.yhy.tradesystem;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.yhy.tradesystem.TradeManager.TradeInfo.TradeType;
import com.yhy.tradesystem.util.Log;


public class TradeManager {

	public static class TradeInfo{
		public static enum TradeType{
			BuySell,
			SellShort//卖空
		}
		
		private TradeType type;//交易类型
		private String tradeName;
		private float position;//仓位
		private float buyPrice= -1.0f;
		private float sellPrice= -1.0f;
		private Date buyTime;
		private Date sellTime;
		private float money;//交易投入的资金
		private float profit;//交易的获利
		
		private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		
		public float getProfit(){
			if(type == TradeType.BuySell ){
				if(sellPrice <= 0.0f)
					return 0.0f;
				
			}
			if(type == TradeType.SellShort){
				if(buyPrice <= 0.0f)
					return 0.0f;
			}
			
			return position*(sellPrice - buyPrice);
		}
		
		public boolean isTradeClosed(){
			if(type == TradeType.BuySell ){
				if(sellPrice >= 0.0f)
					return true;
				
			}
			if(type == TradeType.SellShort){
				if(buyPrice >= 0.0f)
					return true;
			}
			return false;
		}

		public float getMoneySpent() {
			if (type == TradeType.BuySell) {
				return position * buyPrice;

			}
			if (type == TradeType.SellShort) {
				return position * sellPrice;
			}
			return 0.0f;
		}
		
		public Date getBuyTime() {
			return buyTime;
		}
		void setBuyTime(Date buyTime) {
			this.buyTime = buyTime;
		}
		public Date getSellTime() {
			return sellTime;
		}
		void setSellTime(Date sellTime) {
			this.sellTime = sellTime;
		}
		public TradeType getType() {
			return type;
		}
		void setType(TradeType type) {
			this.type = type;
		}
		public float getPosition() {
			return position;
		}
		void setPosition(float position) {
			this.position = position;
		}
		public float getBuyPrice() {
			return buyPrice;
		}
		void setBuyPrice(float buyPrice) {
			this.buyPrice = buyPrice;
		}
		public float getSellPrice() {
			return sellPrice;
		}
		void setSellPrice(float sellPrice) {
			this.sellPrice = sellPrice;
		}
		public String getTradeName() {
			return tradeName;
		}
		void setTradeName(String tradeName) {
			this.tradeName = tradeName;
		}
		@Override
		public String toString() {
			return String.format("%s,%s,%f,%s,%f,%f,%f,%f", 
					tradeName,
					formatter.format(buyTime),
					buyPrice,
					formatter.format(sellTime),
					sellPrice,
					position,
					getMoneySpent(),
					getProfit()
					);
		}

	}
	
	ArrayList<TradeInfo> closeTradeinfo=new ArrayList<TradeManager.TradeInfo>();
	ArrayList<TradeInfo> activeTradeinfo=new ArrayList<TradeManager.TradeInfo>();
	/**记录了资金的转账情况*/
	ArrayList<Float> cashRecord = new ArrayList<Float>();
	
	private float money=0.0f;
	private float initalMoney=0.0f;
	private float commissionRate;//手续费
	
	private float totalProfit;//所有获利相加
	private float totalLost;//所有损失相加
	
	private int winCnt=0;
	private int lossCnt=0;
	private int tradeCnt=0;
	
	public float getInitalMoney() {
		return initalMoney;
	}

	public void setInitalMoney(float initalMoney) {
		this.initalMoney = initalMoney;
		this.money = initalMoney;
		cashRecord.add(initalMoney);
	}

	public float getMoney() {
		return money;
	}
	
	public void putMoneyIn(float newMoney){
		money+=newMoney;
		cashRecord.add(newMoney);
	}


	
	public int startBuySell(String name,Date date,float price,float position){
		if(money >0.0001f){
			TradeInfo info=new TradeInfo();
			info.setType(TradeType.BuySell);
			info.setBuyTime(date);
			info.setBuyPrice(price);
			info.setPosition(position);
			info.setTradeName(name);
			if( info.getMoneySpent() > money ){
				Log.d("yhy",info.getPosition()+" "+info.getBuyPrice()+" buy fail "+ info.getMoneySpent()+" "+money);
				return -1;
			}
			activeTradeinfo.add(info);
			money-=info.getMoneySpent();
			return activeTradeinfo.indexOf(info);
		}
		return -1;
	}
	/**
	 * 计算某一只股票持仓的浮动盈
	 * */
	public float predictProfilt(String name,Date date,float price){
		float spentMoney = 0.0f;
		float currentMoneyValue = 0.0f;
		for (int i = 0; i < activeTradeinfo.size(); i++) {
			TradeInfo info = activeTradeinfo.get(i);
			if(name.equals(info.getTradeName())){
				spentMoney += info.getBuyPrice() * info.getPosition();
				currentMoneyValue += price* info.getPosition();
			}
		}
		
		if(spentMoney == 0.0f){
			return -1f;
		}
		
		return (currentMoneyValue - spentMoney) /spentMoney *100.0f;
	}
	
	public int finishBuySellAll(String name,Date date,float price){
		int ret = 0;
		for (int i = activeTradeinfo.size()-1; i < activeTradeinfo.size(); i++) {
			finishBuySell(i,name,date,price);
		}
		
		ArrayList<TradeInfo> remove = new ArrayList<TradeManager.TradeInfo>();
		for(TradeInfo info:activeTradeinfo){
			if(info.getTradeName().equals(name)){
				remove.add(info);
			}
		}
		
		for(TradeInfo info:remove){
			info.setSellPrice(price);
			info.setSellTime(date);
			activeTradeinfo.remove(info);
			closeTradeinfo.add(info);
			
			float profit = info.getProfit();
			tradeCnt++;
			if(profit > 0.0f){
				winCnt++;
				totalProfit+=profit;
			}else{
				lossCnt++;
				totalLost+=profit;
			}
			money+=info.getPosition()*info.getSellPrice();
			
			ret++;
		}
		
		return ret;
		
	}
	
	public int finishBuySell(int activeTradeId,String name,Date date,float price){
		if( activeTradeId < 0 || activeTradeId > activeTradeinfo.size()-1){
			return -1;
		}
		TradeInfo info = activeTradeinfo.get(activeTradeId);
		
		return finishBuySell(name, date, price, info);
	}

	private int finishBuySell(String name, Date date, float price,
			TradeInfo info) {
		if(info == null){
			return -1;
		}
		if(info.getTradeName().equals(name)){
			info.setSellPrice(price);
			info.setSellTime(date);
			activeTradeinfo.remove(info);
			closeTradeinfo.add(info);
			
			float profit = info.getProfit();
			tradeCnt++;
			if(profit > 0.0f){
				winCnt++;
				totalProfit+=profit;
			}else{
				lossCnt++;
				totalLost+=profit;
			}
			money+=info.getPosition()*info.getSellPrice();
			return closeTradeinfo.indexOf(info);
		}
		return -1;
	}
	
	public TradeInfo getActiveTradeInfo(int activeTradeId){
		if( activeTradeId < 0 || activeTradeId > activeTradeinfo.size()-1){
			return null;
		}
		return activeTradeinfo.get(activeTradeId);
	}
	
	public int getActiveTradeInfoNumber(){
		return activeTradeinfo.size();
	}
	public String dumpReport(){
		float totalMoney = 0.0f;
		for(Float record:cashRecord){
			totalMoney+=record;
		}
		return String.format("交易次数 %d 获利交易 %d 亏损交易 %d\n起始资金 %.2f 当前资金 %.2f 总共使用资金 %.2f 收益 %.2f \n", 
				tradeCnt,
				winCnt,
				lossCnt,
				initalMoney,
				money,
				totalMoney,
				(money - totalMoney)/totalMoney*100f
				);
	}
	
}
